#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>

#include <sys/select.h>

#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "listen.c"
#include "listen_https.c"

#define SERVER_HOST "admin.hdedu.fun"

void print_my_fd_set(fd_set *set) {
    printf("print_fd_set output: { ");
    for (int i = 0; i < FD_SETSIZE; ++i) {
        if (FD_ISSET(i, set)) {
            printf("%d ", i);
        }
    }
    printf("}\n");
}


int start_http(int port) {
    int server_socket, client_socket;
    struct sockaddr_in server_addr, client_addr;
    socklen_t addr_len = sizeof(client_addr);

    // 加载Https的CTX
    SSL_CTX* ctx = load_ctx();

    // 创建服务器套接字
    server_socket = socket(AF_INET, SOCK_STREAM, 0);

    // 配置服务器地址结构
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY;
    server_addr.sin_port = htons(port);

    // 将地址结构绑定到套接字
    bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr));

    // 监听套接字
    if (listen(server_socket, 5) == 0) {
        printf("Proxy server listening 1233..\n");
    } else {
        perror("Error in listening");
        exit(EXIT_FAILURE);
    }

    while (1) {
        // 接受连接
        printf("Start For handle_connection 00... socket = %d \n", client_socket);
        client_socket = accept(server_socket, (struct sockaddr*)&client_addr, &addr_len);
        printf("Start For handle_connection 11... socket= %d\n", client_socket);
        if (client_socket < 0) {
            perror("Error accepting connection :: \n");
            continue;
        }

        // 检查请求是HTTP还是HTTPS 
        char buffer[BUFFER_SIZE];
        memset(buffer, 0, sizeof(buffer));
        
        // int bytes_received = read(client_socket, buffer, sizeof(buffer) - 1);
        int bytes_received = recv(client_socket, buffer, sizeof(buffer), 0);
        if (bytes_received <= 0) {
            perror("client_socket READ Error:: \n");
        }

        if (is_https_request(buffer)) {
            printf("is_https_request 11::: buffer == %s\n", buffer);
            // init_ssl(client_socket, ctx);
            continue;
        }

        // 也可以通过下面判断简单判断是否是 HTTPS
        // if (strncmp(buffer, "CONNECT", 7) == 0) {
        //     printf("HTTPS connection\n");
        // } else {
        //     printf("HTTP connection\n");
        // }

        // 处理直接连接
        // printf("Start For handle_connection ... socket= %d &&& buffer == %s\n", client_socket, buffer);
        printf("Start For handle_connection 22... socket= %d\n", client_socket);
        listen_http(client_socket, buffer);
    }
    return 0;
}

int start_https(int port) {
    int server_socket, client_socket;
    struct sockaddr_in server_addr, client_addr;
    socklen_t addr_len = sizeof(client_addr);

    // 加载Https的CTX
    SSL_CTX* ctx = load_ctx();

    // 创建服务器套接字
    server_socket = socket(AF_INET, SOCK_STREAM, 0);

    // 配置服务器地址结构
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY;
    server_addr.sin_port = htons(port);

    // 将地址结构绑定到套接字
    bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr));

    // 监听套接字
    if (listen(server_socket, 5) == -1) {
        perror("Error in listening Https");
        exit(EXIT_FAILURE);
    }

    

    while (1) {

        // 检查是否还在阻塞当中(用于HTTPS的请求)
        struct sockaddr_in client_addr;
        socklen_t client_len = sizeof(client_addr);

        fd_set readfds;
        FD_ZERO(&readfds);
        FD_SET(server_socket, &readfds);

        struct timeval timeout;
        timeout.tv_sec = 5;  // 5 seconds timeout
        timeout.tv_usec = 0;

        int ready = select(server_socket + 1, &readfds, NULL, NULL, &timeout);

        if (ready == -1) {
            perror("Select error 111 : \n");
            exit(EXIT_FAILURE);
        } else if (ready == 0) {
            // Timeout reached, handle accordingly
            printf("Accept timed out\n");
            continue;
        } else {
            printf("Accept select READ:: server_socket = %d \n", server_socket);
            print_my_fd_set(&readfds);
        }

        // if (inet_pton(AF_INET, SERVER_HOST, &server_addr.sin_addr) <= 0) {
        //     perror("inet_pton");
        //     exit(EXIT_FAILURE);
        // }

        // 如果是阻塞当中
        if (!FD_ISSET(server_socket, &readfds)) {
            perror("Select error::: \n");
            exit(EXIT_FAILURE);
        }


        // 接受连接
        printf("Start For handle_connection 00... socket = %d \n", client_socket);
        // client_socket = accept(server_socket, NULL, NULL);
        client_socket = accept(server_socket, (struct sockaddr*)&client_addr, &addr_len);
        printf("Start For handle_connection 11... socket= %d\n", client_socket);
        if (client_socket < 0) {
            perror("Error accepting connection :: \n");
            continue;
        }

        printf("is_https_request 11:::\n");
        init_ssl(client_socket, ctx);

    }
    return 0;
}



void handle_http_request(int client_socket, const char *request) {
    // 处理 HTTP 请求，这里只是一个简单的示例
    printf("Received HTTP request:\n%s\n", request);

    const char *response = "HTTP/1.1 200 OK\r\nContent-Length: 12\r\n\r\nHello, World!";
    write(client_socket, response, strlen(response));
}

void handle_https_request(int client_socket) {
    // 处理 HTTPS 请求，这里只是一个简单的示例
    const char *response = "HTTP/1.1 200 OK\r\nContent-Length: 12\r\n\r\nHello, World!";
    write(client_socket, response, strlen(response));
}

void main(){
    int result = start_https(8888);
    printf("End main result = %d \n \n", result);
    return;
}